using UniversalAdminSystem.Application.LogManagement.DTOs;
using UniversalAdminSystem.Application.LogManagement.Interfaces;
using UniversalAdminSystem.Domian.LogManagement.Aggregates;
using UniversalAdminSystem.Domian.Core.Interfaces;
using UniversalAdminSystem.Application.Common.Results;
using UniversalAdminSystem.Domian.Core.ValueObjects;
using UniversalAdminSystem.Application.Common.Interfaces;

namespace UniversalAdminSystem.Application.LogManagement.Services;

public class LogManagementAppService : ILogManagementAppService
{
    private readonly IRepository<LogEntry> _logRepository;
    private readonly IUnitOfWork _unitOfWork;

    public LogManagementAppService(
        IRepository<LogEntry> logRepository, 
        IUnitOfWork unitOfWork)
    {
        _logRepository = logRepository;
        _unitOfWork = unitOfWork;
    }

    public async Task<Result<IEnumerable<LogEntryDto>>> GetAllLogsAsync()
    {
        try
        {
            var logs = await _logRepository.GetAllAsync();
            var logDtos = logs.Select(MapToDto);
            return Result<IEnumerable<LogEntryDto>>.Success(logDtos);
        }
        catch (Exception ex)
        {
            return Result<IEnumerable<LogEntryDto>>.Failure($"获取日志列表失败: {ex.Message}");
        }
    }

    public async Task<Result<LogEntryDto?>> GetLogByIdAsync(Guid id)
    {
        try
        {
            var log = await _logRepository.GetByGuidAsync(id);
            if (log == null)
            {
                return Result<LogEntryDto?>.Success(null);
            }

            return Result<LogEntryDto?>.Success(MapToDto(log));
        }
        catch (Exception ex)
        {
            return Result<LogEntryDto?>.Failure($"获取日志详情失败: {ex.Message}");
        }
    }

    public async Task<Result<LogEntryDto>> CreateLogAsync(LogCreateDto createDto)
    {
        try
        {
            var log = LogEntry.Create(
                createDto.Level,
                createDto.Message,
                createDto.Source,
                createDto.UserId.HasValue ? (UserId)createDto.UserId.Value : null,
                createDto.Context,
                createDto.Exception
            );

            await _logRepository.AddAsync(log);
            await _unitOfWork.SaveChangesAsync();
            return Result<LogEntryDto>.Success(MapToDto(log));
        }
        catch (Exception ex)
        {
            return Result<LogEntryDto>.Failure($"创建日志失败: {ex.Message}");
        }
    }

    public async Task<Result<IEnumerable<LogEntryDto>>> GetLogsByLevelAsync(string level)
    {
        try
        {
            var logs = await _logRepository.GetAllAsync();
            var filteredLogs = logs.Where(l => l.Level == level).Select(MapToDto);
            return Result<IEnumerable<LogEntryDto>>.Success(filteredLogs);
        }
        catch (Exception ex)
        {
            return Result<IEnumerable<LogEntryDto>>.Failure($"获取日志失败: {ex.Message}");
        }
    }

    public async Task<Result<IEnumerable<LogEntryDto>>> GetLogsByUserAsync(Guid userId)
    {
        try
        {
            var logs = await _logRepository.GetAllAsync();
            var userLogs = logs.Where(l => l.UserId != null && l.UserId.Value == userId);
            
            var logDtos = userLogs.Select(MapToDto);
            return Result<IEnumerable<LogEntryDto>>.Success(logDtos);
        }
        catch (Exception ex)
        {
            return Result<IEnumerable<LogEntryDto>>.Failure($"获取用户日志失败: {ex.Message}");
        }
    }

    public async Task<Result<IEnumerable<LogEntryDto>>> GetLogsByDateRangeAsync(DateTime start, DateTime end)
    {
        try
        {
            var logs = await _logRepository.GetAllAsync();
            var dateRangeLogs = logs.Where(l => l.Timestamp >= start && l.Timestamp <= end);
            
            var logDtos = dateRangeLogs.Select(MapToDto);
            return Result<IEnumerable<LogEntryDto>>.Success(logDtos);
        }
        catch (Exception ex)
        {
            return Result<IEnumerable<LogEntryDto>>.Failure($"获取日志失败: {ex.Message}");
        }
    }

    public async Task<Result<IEnumerable<LogEntryDto>>> GetLogsBySourceAsync(string source)
    {
        try
        {
            var logs = await _logRepository.GetAllAsync();
            var sourceLogs = logs.Where(l => l.Source == source);
            
            var logDtos = sourceLogs.Select(MapToDto);
            return Result<IEnumerable<LogEntryDto>>.Success(logDtos);
        }
        catch (Exception ex)
        {
            return Result<IEnumerable<LogEntryDto>>.Failure($"获取日志失败: {ex.Message}");
        }
    }

    public async Task<Result> DeleteLogAsync(Guid id)
    {
        try
        {
            var log = await _logRepository.GetByGuidAsync(id);
            if (log == null)
            {
                return Result.Failure("日志不存在");
            }

            await _logRepository.RemoveAsync(id);
            await _unitOfWork.SaveChangesAsync();
            return Result.Success("日志删除成功");
        }
        catch (Exception ex)
        {
            return Result.Failure($"删除日志失败: {ex.Message}");
        }
    }

    public async Task<Result> ClearLogsAsync()
    {
        try
        {
            var logs = await _logRepository.GetAllAsync();
            foreach (var log in logs)
            {
                await _logRepository.RemoveAsync(log.Id);
            }
            await _unitOfWork.SaveChangesAsync();
            return Result.Success("日志清空成功");
        }
        catch (Exception ex)
        {
            return Result.Failure($"清空日志失败: {ex.Message}");
        }
    }

    private static LogEntryDto MapToDto(LogEntry l) => new(
        l.Id, l.Level, l.Message, l.Source, l.UserId?.Value, l.Timestamp, l.Context, l.Exception
    );
} 